using System.Collections.ObjectModel;
using System.Data;
using System.Globalization;
using Chaotic.DataBase.DataAccess;
using Chaotic.DataBase.DataAccess.Entity;
using Chaotic.DataBase.DBAccessLibrary.Common;
using Chaotic.DataBase.DBAccessLibrary.Interface;
using Chaotic.DataBase.DBAccessLibrary.Model;

namespace Chaotic.DataBase.DBAccessLibrary.DBAccessLibrary;

public class DatabaseOperations : IOperations
{
	private IDbTransaction? _transaction;

	public bool CreateDBEntity(ObservableCollection<DataBaseEntity?> list, Action<string, int> log, Action<Action> begioninvoke)
	{
		if (SysCache.DBConnection == null)
		{
			log("当前连接不可用。", 1);
			return false;
		}
		string text = IsConnectDB(SysCache.DBConnection);
		if (text != string.Empty)
		{
			log("当前数据库无法连接。异常：" + text,1);
			begioninvoke(delegate
			{
				DBEntity dBEntity = list.SelectMany(o => o.ChildNodes).Cast<DBEntity>().FirstOrDefault(o => o.Name == SysCache.DBConnection.DataBase && o.ConnectionSource?.Server == SysCache.DBConnection.Server);
				if (dBEntity != null)
				{
					dBEntity.Status = DBConnectStatus.Off;
				}
			});
			return false;
		}
		ServerEntity? server = new ServerEntity(SysCache.DBConnection.Server)
		{
			ImageUrl = "/Images/Tree/computers.png"
		};
		DBEntity? db = CreateDBEntity(SysCache.DBConnection);
		DBEntity test = new DBEntity("正在连接，请等待……")
		{
			ImageUrl = "/Images/Tree/blue-loading.gif"
		};
		begioninvoke(delegate
		{
			DataBaseEntity? dataBaseEntity = list.FirstOrDefault(o => o?.Name == server.Name);
			if (dataBaseEntity != null)
			{
                if (dataBaseEntity.ChildNodes != null)
                {
                    DataBaseEntity? dataBaseEntity2 = dataBaseEntity.ChildNodes.FirstOrDefault(o => o?.Name == db?.Name);
                    if (dataBaseEntity2 != null)
                    {
                        dataBaseEntity.ChildNodes.Remove(dataBaseEntity2);
                    }
                }

                server = dataBaseEntity as ServerEntity;
			}
			else
			{
				list.Add(server);
			}
			if (server != null)
			{
				server.ChildNodes?.Add(test);
				server.IsExpanded = true;
			}
		});
		SysCache.TableList = new List<TableEntity>();
		SysCache.ProcList = new List<ProcEntity>();
		SysCache.ViewList = new List<ViewEntity>();
		GetDbEntitys(log, SysCache.DBConnection, isLoadChina: true, db);
		begioninvoke(delegate
		{
			server.ChildNodes?.Remove(test);
			server.ChildNodes?.Add(db);
			foreach (DBEntity item in from DBEntity o in list.SelectMany((o) => o.ChildNodes)
				where o.Status == DBConnectStatus.Connected
				select o)
			{
				if (item.Name != db?.Name)
				{
					item.Status = DBConnectStatus.Off;
				}
				else if (item.Name == db?.Name && item.ConnectionSource?.Server != db?.ConnectionSource?.Server)
				{
					item.Status = DBConnectStatus.Off;
				}
			}

            if (db != null)
            {
                db.Status = DBConnectStatus.Connected;
                db.IsExpanded = true;
            }
        });
		log("数据库连接成功", 0);
		return true;
	}

	private DbEntityCache GetDbEntitys(Action<string, int> log, ConnectionModel? connectModel, bool isLoadChina, DBEntity? db = null)
	{
		DataSet? chds = null;
		List<TableInfo> tinfo = new List<TableInfo>();
		List<ColumnInfo> cinfo = new List<ColumnInfo>();
		List<IndexInfo> iinfo = new List<IndexInfo>();
		List<RelationshipInfo> rinfo = new List<RelationshipInfo>();
		List<ViewInfo> vinfo = new List<ViewInfo>();
		List<ProcInfo> pinfo = new List<ProcInfo>();
		List<ProcParamInfo> ppinfo = new List<ProcParamInfo>();
		ConnectDB(connectModel, delegate (ConnectionModel? connect, IDataAccess dataaccess)
		{
			log("获取数据库相关信息", 0);

			void Action2(string msg, Action action)
			{
				try
				{
					action();
				}
				catch (Exception ex)
				{
					log(msg + "获取失败.--" + ex.Message, 1);
				}
			}

			if (dataaccess is IDataStructure structue)
			{
				Action2("表信息", delegate
				{
					structue.FillingTables(tinfo);
				});
				Action2("列信息", delegate
				{
					structue.FillingColumns(cinfo);
				});
				Action2("索引信息", delegate
				{
					structue.FillingIndexs(iinfo);
				});
				Action2("关系信息", delegate
				{
					structue.FillingRelations(rinfo);
				});
				Action2("视图信息", delegate
				{
					structue.FillingViews(vinfo);
				});
				Action2("存储过程信息", delegate
				{
					structue.FillingProcs(pinfo);
				});
				Action2("存储过程参数信息", delegate
				{
					structue.FillingProcParams(ppinfo);
				});
				if (isLoadChina)
				{
					Action2("中文对照信息", delegate
					{
						string? chTableSql = DBOperatorFactory.GetGrammar(connect)?.GetChTableSql;
						if (chTableSql != null)
							chds = dataaccess.ExecuteDataset(chTableSql);
					});
				}
			}
		});
		log("构建实体集合", 0);
		DescriptionEntity descriptionEntity = CreateTableEntity(tinfo, cinfo, chds, rinfo, iinfo);
		DescriptionEntity descriptionEntity2 = CreateViewEntity(vinfo, cinfo);
		DescriptionEntity descriptionEntity3 = CreateProcEntity(pinfo, ppinfo);
		if (db != null)
		{
			db.ChildNodes?.Add(descriptionEntity);
			db.ChildNodes?.Add(descriptionEntity2);
			db.ChildNodes?.Add(descriptionEntity3);
		}


		DbEntityCache dbEntityCache = new DbEntityCache
		{
			TableList = descriptionEntity.ChildNodes.Cast<TableEntity>(),
			ViewList = descriptionEntity2.ChildNodes.Cast<ViewEntity>(),
			ProcList = descriptionEntity3.ChildNodes.Cast<ProcEntity>()
		};
		return dbEntityCache;

	}

	private DBEntity? CreateDBEntity(ConnectionModel? connect)
	{
        if (connect?.DataBase != null)
        {
            DBEntity? dBEntity = new DBEntity(connect.DataBase)
            {
                ConnectionSource = connect,
                Status = DBConnectStatus.Connected
            };
            return dBEntity;
        }
		return null;
    }

	private DescriptionEntity CreateTableEntity(List<TableInfo>? tbds, List<ColumnInfo> columnds, DataSet? chds, IEnumerable<RelationshipInfo>? relds, IEnumerable<IndexInfo>? indexds)
	{
		DescriptionEntity descriptionEntity = new DescriptionEntity("表")
        {
            ImageUrl = "/Images/Tree/tableGroup.png"
        };
        DescriptionEntity descriptionEntity2 = descriptionEntity;
		if (tbds is { Count: > 0 })
		{
			foreach (TableInfo tbd in tbds)
			{
				TableEntity tableEntity = new TableEntity(tbd.TableName)
                {
                    PrimaryKeyName = tbd.PrimaryKeyName
                };
                TableEntity tableEntity2 = tableEntity;
				tableEntity2.ChildNodes?.Add(new TableInfoEntity("列")
				{
					ImageUrl = "/Images/Tree/columns.png"
				});
				tableEntity2.ChildNodes?.Add(new TableInfoEntity("外键")
				{
					ImageUrl = "/Images/Tree/relationship.png"
				});
				tableEntity2.ChildNodes?.Add(new TableInfoEntity("索引")
				{
					ImageUrl = "/Images/Tree/index.png"
				});
				descriptionEntity2.ChildNodes?.Add(tableEntity2);
			}
			foreach (ColumnInfo item3 in from o in columnds
				where o.IsForeignKey || o.IsPrimaryKey
				orderby o.IsPrimaryKey descending, o.IsForeignKey descending
				select o)
			{
				ColumnInfo columnrow1 = item3;
                if (descriptionEntity2.ChildNodes != null)
                {
                    DataBaseEntity dataBaseEntity = descriptionEntity2.ChildNodes.FirstOrDefault((o) => o.Name == columnrow1.TableName);
                    if (dataBaseEntity != null)
                    {
                        FieldEntity fieldEntity = new FieldEntity(item3.ColumnName)
                        {
                            TypeName = item3.TypeName,
                            Scale = item3.DataScale,
                            Length = item3.Length,
                            Index = item3.ColumnIndex,
                            IsNull = item3.IsNull,
                            DefaultValue = item3.DefaultValue,
                            IsForeignKey = item3.IsForeignKey,
                            IsPrimaryKey = item3.IsPrimaryKey,
                            TableName = item3.TableName
                        };
                        FieldEntity item = fieldEntity;
                        dataBaseEntity.ChildNodes[0]?.ChildNodes.Add(item);
                    }
                }
            }
			foreach (ColumnInfo item4 in columnds.Where((o) => o is { IsForeignKey: false, IsPrimaryKey: false }))
			{
				ColumnInfo columnrow2 = item4;
				DataBaseEntity dataBaseEntity2 = descriptionEntity2.ChildNodes.FirstOrDefault((o) => o.Name == columnrow2.TableName);
				if (dataBaseEntity2 != null)
				{
					FieldEntity fieldEntity2 = new FieldEntity(item4.ColumnName)
                    {
                        TypeName = item4.TypeName,
                        Scale = item4.DataScale,
                        Length = item4.Length,
                        Index = item4.ColumnIndex,
                        IsNull = item4.IsNull,
                        DefaultValue = item4.DefaultValue,
                        IsForeignKey = item4.IsForeignKey,
                        IsPrimaryKey = item4.IsPrimaryKey,
                        TableName = item4.TableName
                    };
                    FieldEntity item2 = fieldEntity2;
					dataBaseEntity2.ChildNodes[0]?.ChildNodes.Add(item2);
				}
			}
			CreateRelationshipEntity(descriptionEntity2, relds);
			CreateIndexEntity(descriptionEntity2, indexds);
			SetChName(chds, descriptionEntity2);
		}
		return descriptionEntity2;
	}

	private void CreateRelationshipEntity(DescriptionEntity table, IEnumerable<RelationshipInfo>? relds)
	{
		if (relds == null)
		{
			return;
		}
		foreach (RelationshipInfo reld in relds)
		{
			RelationshipInfo relrow1 = reld;
			DataBaseEntity dataBaseEntity = table.ChildNodes.FirstOrDefault((o) => o.Name == relrow1.TableName);
			if (dataBaseEntity != null)
			{
				string? text = reld.ColumnName + "->[" + reld.RelationTableName + "]." + reld.RelationColumnName;
				if (reld.IsCascadingDelete)
				{
					text += "(↓D)";
				}
				if (reld.IsCascadingUpdate)
				{
					text += "(↑U)";
				}
				RelationshipEntity relationshipEntity = new RelationshipEntity(text)
                {
                    RefKeyName = reld.RefKeyName,
                    ColumnName = reld.ColumnName,
                    RelationTableName = reld.RelationTableName,
                    RelationColumnName = reld.RelationColumnName,
                    IsCascadingUpdate = reld.IsCascadingUpdate,
                    IsCascadingDelete = reld.IsCascadingDelete
                };
                RelationshipEntity item = relationshipEntity;
				dataBaseEntity.ChildNodes[1]?.ChildNodes.Add(item);
			}
		}
	}

	private void CreateIndexEntity(DescriptionEntity table, IEnumerable<IndexInfo>? indexds)
	{
		if (indexds == null)
		{
			return;
		}
		foreach (IndexInfo indexd in indexds)
		{
			IndexInfo indexrow1 = indexd;
			DataBaseEntity dataBaseEntity = table.ChildNodes.FirstOrDefault((o) => o.Name == indexrow1.TableName);
			if (dataBaseEntity != null)
			{
				string? indexName = indexd.IndexName;
				bool flag = false;
				IndexDescriptionEntity indexDescriptionEntity = dataBaseEntity.ChildNodes[2]?.ChildNodes.FirstOrDefault((o) => o.Name == indexName) as IndexDescriptionEntity;
				if (indexDescriptionEntity == null)
				{
					IndexDescriptionEntity indexDescriptionEntity2 = new IndexDescriptionEntity(indexName)
                        {
                            IsUnique = indexd.IsUnique
                        };
                        indexDescriptionEntity = indexDescriptionEntity2;
					flag = true;
				}
				IndexEntity indexEntity = new IndexEntity(indexd.ColumnName)
                {
                    Sequence = indexd.Sequence,
                    ColumnName = indexd.ColumnName
                };
                IndexEntity item = indexEntity;
				indexDescriptionEntity.ChildNodes.Add(item);
				if (flag)
				{
					dataBaseEntity.ChildNodes[2]?.ChildNodes.Add(indexDescriptionEntity);
				}
			}
		}
	}

	private DescriptionEntity CreateViewEntity(IEnumerable<ViewInfo> vinfo, List<ColumnInfo> cinfo)
	{
		DescriptionEntity descriptionEntity = new DescriptionEntity("视图")
        {
            ImageUrl = "/Images/Tree/viewGroup.png"
        };
        foreach (ViewInfo item2 in vinfo)
		{
			ViewEntity viewEntity = new ViewEntity(item2.ViewName)
            {
                Content = item2.Content
            };
            ViewEntity viewEntity2 = viewEntity;
			ViewInfo entity1 = item2;
			foreach (ColumnInfo item3 in cinfo.Where((o) => o.TableName == entity1.ViewName))
			{
				FieldEntity fieldEntity = new FieldEntity(item3.ColumnName)
                {
                    TypeName = item3.TypeName,
                    Length = item3.Length,
                    Scale = item3.DataScale,
                    IsPrimaryKey = item3.IsPrimaryKey,
                    IsNull = item3.IsNull
                };
                FieldEntity item = fieldEntity;
				viewEntity2.ChildNodes.Add(item);
			}
			descriptionEntity.ChildNodes.Add(viewEntity2);
		}
		return descriptionEntity;
	}

	private DescriptionEntity CreateProcEntity(IEnumerable<ProcInfo> pinfo, List<ProcParamInfo> ppinfo)
	{
		DescriptionEntity descriptionEntity = new DescriptionEntity("存储过程")
        {
            ImageUrl = "/Images/Tree/procGroup.png"
        };
        foreach (ProcInfo item2 in pinfo)
		{
			ProcEntity procEntity = new ProcEntity(item2.ProcName)
            {
                Content = item2.Content
            };
            ProcEntity procEntity2 = procEntity;
			ProcInfo entity1 = item2;
			foreach (ProcParamInfo item3 in ppinfo.Where((o) => o.ProcId == entity1.ProcId))
			{
				ProcParamEntity procParamEntity = new ProcParamEntity(item3.ProcParamName)
                {
                    Length = item3.Length,
                    TypeName = item3.TypeName,
                    Status = item3.State,
                    Index = item3.ParamIndex,
                    Scale = item3.DataScale
                };
                ProcParamEntity item = procParamEntity;
				procEntity2.ChildNodes.Add(item);
			}
			descriptionEntity.ChildNodes.Add(procEntity2);
		}
		return descriptionEntity;
	}

	private void SetChName(DataSet? ds, DescriptionEntity table)
	{
		if (ds == null || ds.Tables.Count == 0)
		{
			return;
		}
		foreach (DataRow row in ds.Tables[0].Rows)
		{
			DataRow dr1 = row;
			DataBaseEntity dataBaseEntity = table.ChildNodes.FirstOrDefault((o) => o.Name == dr1["TABLENAME"].ToString());
			if (dataBaseEntity != null)
			{
				if (string.IsNullOrEmpty(dataBaseEntity.ChName))
				{
					dataBaseEntity.ChName = row["CHINATABLENAME"].ToString()?.Trim();
				}
				DataBaseEntity dataBaseEntity2 = dataBaseEntity.ChildNodes[0]?.ChildNodes.FirstOrDefault((o) => o.Name == dr1["COLUMNNAME"].ToString());
				if (dataBaseEntity2 != null)
				{
					dataBaseEntity2.ChName = row["CHINACOLUMNNAME"].ToString()?.Trim();
				}
			}
		}
	}

	public DbEntityCache GetDbInfos(ConnectionModel? connection, Action<string, int> log)
	{
		if (connection == null)
		{
			return null;
		}
		return GetDbEntitys(log, connection, isLoadChina: false);
	}

	public void SaveDescription(TableEntity table, FieldEntity field, string? newChStr, bool isnewTable, TransactionType transaction = TransactionType.NoTransaction)
	{
		string? isExistChTableSql = DBOperatorFactory.GetGrammar(SysCache.DBConnection)?.IsExistChTableSql;
		DataSet? dataSet = ExecSqlToDS(isExistChTableSql);
		if (dataSet is { Tables.Count: > 0 } && dataSet.Tables[0].Rows.Count == 0)
		{
			if (!isnewTable)
			{
				return;
			}
			isExistChTableSql = "create table T_FIELD_DICTIONARY (\r\n                           TABLENAME                        VARCHAR(50)        Not Null,        --表名\r\n                           FIELDNAME                        VARCHAR(30)        Not Null,        --字段名\r\n                           CHINESENAME                      VARCHAR(50)            Null,        --中文名\r\n                           CHINESETABLENAME                 VARCHAR(40)            Null,        --中文表名\r\n                           COMMENTARY                       VARCHAR(100)           Null,        --备注\r\n                           COMPUTEFIELD                     VARCHAR(4)             Null,        --计算字段\r\n                           COMPUTEFORMULA                   VARCHAR(60)            Null,        --计算公式\r\n                           DICTIONARYID                     VARCHAR(10)            Null,        --字典ID\r\n                           FIELDLENGTH                      INTEGER                Null,        --字段长度\r\n                           FIELDPRECISION                   INTEGER                Null,        --字段精度\r\n                           FIELDTYPE                        VARCHAR(20)            Null,        --字段类型\r\n                           ISFORERGNKEY                     VARCHAR(2)             Null,        --外键\r\n                           ISPRIMARY                        VARCHAR(2)             Null,        --主键\r\n                           SHOW                             VARCHAR(4)             Null,        --显示\r\n                           SHOWORDER                        INTEGER                Null,        --显示顺序\r\n                           SHOWWIDTH                        INTEGER                Null,        --显示宽度\r\n                           primary key  (TABLENAME,FIELDNAME)\r\n                        )";
			ExecSql(isExistChTableSql, SysCache.DBConnection, null, transaction);
		}
		isExistChTableSql = $"select TABLENAME from T_FIELD_DICTIONARY where TABLENAME='{table.TransName}' and FIELDNAME ='{field.TransName}'";
		dataSet = ExecSqlToDS(isExistChTableSql, SysCache.DBConnection, null, transaction);
		if (dataSet is { Tables.Count: > 0 })
		{
			isExistChTableSql = ((dataSet.Tables[0].Rows.Count <= 0) ? "insert into T_FIELD_DICTIONARY(TABLENAME,CHINESETABLENAME,FIELDNAME,CHINESENAME,FIELDTYPE,FIELDLENGTH,FIELDPRECISION,ISPRIMARY,ISFORERGNKEY) values('{0}','{1}','{2}','{3}','{4}',{5},{6},'{7}','{8}')" : "update T_FIELD_DICTIONARY set CHINESETABLENAME='{1}',CHINESENAME='{3}',FIELDTYPE='{4}',FIELDLENGTH={5},FIELDPRECISION={6},ISPRIMARY='{7}',ISFORERGNKEY='{8}' where TABLENAME='{0}' and FIELDNAME ='{2}' ");
			isExistChTableSql = string.Format(isExistChTableSql, table.TransName, table.TransChName, field.TransName, string.IsNullOrEmpty(newChStr) ? field.ChName : newChStr, field.TypeName, string.IsNullOrEmpty(field.Length) ? "NULL" : field.Length, string.IsNullOrEmpty(field.Scale) ? "NULL" : field.Scale, field.IsPrimaryKey ? "1" : "0", field.IsForeignKey ? "1" : "0");
			ExecSql(isExistChTableSql, SysCache.DBConnection, null, transaction);
		}
	}

	public List<TypeInfoEntity> GetTypeInfos(ConnectionModel? connection = null)
	{
		connection ??= SysCache.DBConnection;
		if (SysCache.TypeList != null)
		{
			return SysCache.TypeList.ToList();
		}
		List<TypeInfoEntity> typeList = new List<TypeInfoEntity>();
        ConnectDB(connection, delegate (ConnectionModel connect, IDataAccess dataaccess)
		{
			if (dataaccess is IDataStructure dataStructure)
			{
				List<TypeNameInfos> list = new List<TypeNameInfos>();
				dataStructure.FillingTypeInfos(list);
				list.ForEach(delegate(TypeNameInfos o)
				{
					typeList.Add(new TypeInfoEntity
					{
						Length = o.Length,
						TypeName = o.TypeName,
						Scale = o.Scale
					});
				});
			}
		});
		SysCache.TypeList = typeList;
		return typeList;
	}

	public void RollbackTransaction(ConnectionModel? connect)
	{
		if (_transaction != null)
		{
			_transaction.Rollback();
			_transaction = null;
		}
		IDataAccess cache = MemoryCacheManager.GetCache<IDataAccess>(connect.GetHashCode().ToString(CultureInfo.InvariantCulture));
		if (cache != null)
		{
			cache.Close();
            MemoryCacheManager.RemoveCache(connect.GetHashCode().ToString(CultureInfo.InvariantCulture));
		}
	}

	public void CommitTransaction(ConnectionModel? connect)
	{
		if (_transaction != null)
		{
			_transaction.Commit();
			_transaction = null;
		}
		IDataAccess cache = MemoryCacheManager.GetCache<IDataAccess>(connect.GetHashCode().ToString(CultureInfo.InvariantCulture));
		if (cache != null)
		{
			cache.Close();
            MemoryCacheManager.RemoveCache(connect.GetHashCode().ToString(CultureInfo.InvariantCulture));
		}
	}

	public void ConnectDB(ConnectionModel? connect, Action<ConnectionModel?, IDataAccess?> exec, TransactionType transaction = TransactionType.NoTransaction)
	{
		if (connect == null)
		{
			throw new Exception("当前链接已断开，请重新连接.");
		}
		IDataAccess? dataAccess = null;
		if (transaction == TransactionType.Transaction)
		{
			dataAccess = MemoryCacheManager.GetCache<IDataAccess>(connect.GetHashCode().ToString(CultureInfo.InvariantCulture));
		}
		if (dataAccess == null)
		{
			PersistenceProperty.DatabaseType = DBOperatorFactory.GetLocalGrammar(connect).GetConnectionStr(out var connectStr);
			connect.ConnectionStr = connectStr;
			PersistenceProperty.ConnectionString = connectStr;
			dataAccess = DataAccessFactory.Instance.CreateDataAccess();
			if (transaction == TransactionType.Transaction)
			{
                MemoryCacheManager.SetCache(connect.GetHashCode().ToString(CultureInfo.InvariantCulture), dataAccess, 5);
			}
		}
		if (dataAccess != null)
		{
			dataAccess.Open();
			if (transaction == TransactionType.Transaction && _transaction == null)
			{
				_transaction = dataAccess.BeginTransaction();
			}
			try
			{
				exec?.Invoke(connect, dataAccess);
			}
			finally
			{
				if (transaction == TransactionType.NoTransaction)
				{
					dataAccess.Close();
				}
			}
		}
	}

	public void ConnectDB(ConnectionModel? connect)
	{
		if (connect == null)
		{
			throw new Exception("当前链接无效，请重新配置.");
		}
		PersistenceProperty.DatabaseType = DBOperatorFactory.GetLocalGrammar(connect).GetConnectionStr(out var connectStr);
		connect.ConnectionStr = connectStr;
		PersistenceProperty.ConnectionString = connectStr;
		IDataAccess? dataAccess = DataAccessFactory.Instance.CreateDataAccess();
		if (dataAccess != null)
		{
			dataAccess.Open();
			dataAccess.Close();
			SysCache.DBConnection = connect;
		}
	}

	public void ExecSql(string? sql, ConnectionModel? connect = null, List<DBParam>? paramlist = null, TransactionType transaction = TransactionType.NoTransaction)
    {
        connect ??= SysCache.DBConnection;
        ConnectDB(connect, delegate(ConnectionModel c, IDataAccess i)
		{
			if (paramlist is { Count: > 0 })
			{
				QueryParameterCollection qpc = new QueryParameterCollection();
				paramlist.ForEach(delegate(DBParam o)
				{
					if (string.IsNullOrEmpty(o.TypeName))
					{
						qpc.Add("@" + o.Name, o.Value);
					}
					else
					{
						qpc.Add(new QueryParameter("@" + o.Name, o.Value, o.TypeName, ParameterDirection.Input));
					}
				});
				i.ExecuteNonQuery(sql, qpc);
			}
			else
			{
				i.ExecuteNonQuery(sql);
			}
		}, transaction);
    }

	public object? ExecScalar(string? sql, ConnectionModel? connect = null, List<DBParam> paramlist = null, TransactionType transaction = TransactionType.NoTransaction)
	{
		connect ??= SysCache.DBConnection;
		object? result = null;
		ConnectDB(connect, delegate(ConnectionModel c, IDataAccess i)
		{
			if (paramlist is { Count: > 0 })
			{
				QueryParameterCollection qpc = new QueryParameterCollection();
				paramlist.ForEach(delegate(DBParam o)
				{
					if (string.IsNullOrEmpty(o.TypeName))
					{
						qpc.Add(o.Name, o.Value);
					}
					else
					{
						qpc.Add(new QueryParameter(o.Name, o.Value, o.TypeName, ParameterDirection.Input));
					}
				});
				result = i.ExecuteScalar(sql, qpc);
			}
			else
			{
				result = i.ExecuteScalar(sql);
			}
		}, transaction);
		return result;
	}

	public int ExecNonQuery(string? sql, ConnectionModel? connect = null, List<DBParam>? paramlist = null, TransactionType transaction = TransactionType.NoTransaction)
	{
		if (connect == null)
		{
			connect = SysCache.DBConnection;
		}
		int result = 0;
		ConnectDB(connect, delegate(ConnectionModel c, IDataAccess i)
		{
			if (paramlist is { Count: > 0 })
			{
				QueryParameterCollection qpc = new QueryParameterCollection();
				paramlist.ForEach(delegate(DBParam o)
				{
					if (string.IsNullOrEmpty(o.TypeName))
					{
						qpc.Add(o.Name, o.Value);
					}
					else
					{
						qpc.Add(new QueryParameter(o.Name, o.Value, o.TypeName, ParameterDirection.Input));
					}
				});
				result = i.ExecuteNonQuery(sql, qpc);
			}
			else
			{
				result = i.ExecuteNonQuery(sql);
			}
		}, transaction);
		return result;
	}

	public DataSet? ExecSqlToDS(string? sql, ConnectionModel? connect = null, List<DBParam> paramlist = null, TransactionType transaction = TransactionType.NoTransaction)
	{
		DataSet? ds = null;
		if (connect == null)
		{
			connect = SysCache.DBConnection;
		}
		ConnectDB(connect, delegate(ConnectionModel c, IDataAccess i)
		{
			ds = new DataSet();
			if (paramlist is { Count: > 0 })
			{
				QueryParameterCollection qpc = new QueryParameterCollection();
				paramlist.ForEach(delegate(DBParam o)
				{
					if (string.IsNullOrEmpty(o.TypeName))
					{
						qpc.Add(o.Name, o.Value);
					}
					else
					{
						qpc.Add(new QueryParameter(o.Name, o.Value, o.TypeName, ParameterDirection.Input));
					}
				});
				ds = i.ExecuteDataset(sql, qpc);
			}
			else
			{
				ds = i.ExecuteDataset(sql);
			}
		}, transaction);
		return ds;
	}

	public DataSet? ExecProc(string? procName, List<DBParam> paramlist, out Dictionary<string?, object?> outdic, ConnectionModel? connect = null, TransactionType transaction = TransactionType.NoTransaction)
	{
		DataSet? result = null;
		if (connect == null)
		{
			connect = SysCache.DBConnection;
		}
		Dictionary<string?, object?> dic = new Dictionary<string?, object?>();
		ConnectDB(connect, delegate(ConnectionModel c, IDataAccess i)
		{
			if (paramlist is { Count: > 0 })
			{
				QueryParameterCollection qpc = new QueryParameterCollection();
				paramlist.ForEach(delegate(DBParam o)
				{
					QueryParameter queryParameter = null;
					queryParameter = ((!string.IsNullOrEmpty(o.TypeName)) ? new QueryParameter(o.Name, o.Value, o.TypeName, (ParameterDirection)o.ParamType) : new QueryParameter(o.Name, o.Value)
					{
						Direction = (ParameterDirection)o.ParamType
					});
					qpc.Add(queryParameter);
				});
				result = i.ExecuteDataset(CommandType.StoredProcedure, procName, qpc);
				{
					foreach (DBParam item in paramlist.Where((DBParam o) => o.ParamType == 2))
					{
						dic.Add(item.Name, qpc[item.Name].Value);
					}
					return;
				}
			}
			result = i.ExecuteDataset(CommandType.StoredProcedure, procName);
		}, transaction);
		outdic = dic;
		return result;
	}

	public string IsConnectDB(ConnectionModel? connect)
	{
		try
		{
			if (connect == null)
			{
				return "连接实体不能为空";
			}
			PersistenceProperty.DatabaseType = DBOperatorFactory.GetLocalGrammar(connect).GetConnectionStr(out var connectStr);
			PersistenceProperty.ConnectionString = connectStr;
			IDataAccess? dataAccess = DataAccessFactory.Instance.CreateDataAccess();
			if (dataAccess != null)
			{
				dataAccess.Open();
				dataAccess.Close();
			}
			return string.Empty;
		}
		catch (Exception ex)
		{
			return ex.Message;
		}
	}
}
